/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Application.MainForm;
import Application.*;
import Application.Elements.*;
import java.awt.*;
import java.awt.image.BufferedImage;
/**
 *
 * @author Stikmann
 */
public class NetworkControl extends Panel {

    /**
     * A modell
     */
    private Network net;

    /**
     * A statikus elemeket (AND,OR,stb.) tartalmazo hatterkep.
     */
    private Image hatter;

    /**
     * A modell valtozasaira figyelo observer
     */
    private NetworkUpdateListener updatelistener;

    /**
     * A modellhez tartozo hatterkep es az interaktv elemek controljainak
     * legyartasaert felelos fuggveny
     */
    private void createAll(){
        GraphLayout layout=new GraphLayout(net.collection.size());
        for(CheckResetSimulate crs:net.collection)
             if(crs instanceof Element) {
                 Element elem=(Element)crs;
                 int ind=net.collection.indexOf(elem);
                 for (Element elem2:elem.inputs){
                    int ind2=net.collection.indexOf(elem2);
                    if (ind2>=0)
                        layout.addEdge(ind2, ind);

                    for(CheckResetSimulate composite:net.collection)
                        if(composite instanceof CompositeElement)
                            if(((CompositeElement)composite).isOutput(elem2))
                                layout.addEdge(net.collection.indexOf(composite),ind);
                 }
             }else
             if(crs instanceof CompositeElement){
                 int ind=net.collection.indexOf(crs);
                 for(int i=0;i<1000;++i){
                     Element pin=((CompositeElement)crs).getInput(i);
                     if (pin==null)
                         break;
                     for (Element elem2:pin.inputs){
                        int ind2=net.collection.indexOf(elem2);
                        if (ind2>=0)
                            layout.addEdge(ind2, ind);
                        
                        for(CheckResetSimulate composite:net.collection)
                        if(composite instanceof CompositeElement)
                            if(((CompositeElement)composite).isOutput(elem2))
                                layout.addEdge(net.collection.indexOf(composite),ind);
                    }
                 }
             }

        layout.doLayout();

        hatter=new BufferedImage(layout.maxx,layout.maxy,BufferedImage.TYPE_INT_RGB);
        setSize(layout.maxx,layout.maxy);
        Graphics g=hatter.getGraphics();
        g.setColor(Color.white);
        g.fillRect(0,0,layout.maxx,layout.maxy);
        g.setColor(Color.black);

        for(GraphLayout.GraphEdge edge:layout.edges){
                GraphLayout.GraphNode node1=layout.nodes[edge.honnan];
                GraphLayout.GraphNode node2=layout.nodes[edge.hova];
                g.drawLine(node1.x+55,node1.y+55,node2.x+55,node2.y+55);
                int kx=(node1.x*3+node2.x*2)/5+55;
                int ky=(node1.y*3+node2.y*2)/5+55;
                int dx=node1.x-node2.x;
                int dy=node1.y-node2.y;
                double dst=Math.sqrt(dx*dx+dy*dy)*0.15;
                dx/=dst;
                dy/=dst;
                int pontokx[]={0,0,0}, pontoky[]={0,0,0};

                if (edge.reversed){
                    pontokx[0]=kx;
                    pontokx[1]=kx-dx-dy;
                    pontokx[2]=kx-dx+dy;

                    pontoky[0]=ky;
                    pontoky[1]=ky+dx-dy;
                    pontoky[2]=ky-dx-dy;
                }else{
                    pontokx[0]=kx;
                    pontokx[1]=kx+dx+dy;
                    pontokx[2]=kx+dx-dy;

                    pontoky[0]=ky;
                    pontoky[1]=ky-dx+dy;
                    pontoky[2]=ky+dx+dy;
                }
                g.fillPolygon(pontokx, pontoky, 3);
        }

        int i=0;
        for(CheckResetSimulate crs:net.collection)
        {
            if(crs instanceof Element) {
                Element elem=(Element)crs;
                String nev=elem.name;
                String tipus=elem.getClass().getSimpleName();
                GraphLayout.GraphNode node=layout.nodes[net.collection.indexOf(elem)];
                int x=20+node.x;
                int y=20+node.y;
                
                g.setColor(Color.white);
                g.fillRect( x, y, 72, 72);
                g.setColor(Color.black);
                g.drawRect( x, y, 72, 72);

                g.drawString(nev,x+5,y+15);
                g.drawString(tipus,x+5,y+30);

                if (elem instanceof BTN){
                    BTNControl cnt=new BTNControl((BTN)elem,updatelistener);
                    add(cnt);
                    cnt.setLocation(x+1, y+35);
                }

                if (elem instanceof LED){
                    LEDControl cnt=new LEDControl((LED)elem);
                    add(cnt);
                    cnt.setLocation(x+1, y+35);
                }

                if (elem instanceof Osc){
                    OscControl cnt=new OscControl((Osc)elem);
                    add(cnt);
                    cnt.setLocation(x+1, y+35);
                }

                if (elem instanceof Wavegen){
                    WavegenControl cnt=new WavegenControl((Wavegen)elem,updatelistener);
                    add(cnt);
                    cnt.setLocation(x+1, y+35);
                }
                ++i;
            }
            else if(crs instanceof CompositeElement){
                CompositeElement elem=(CompositeElement)crs;
                String nev=elem.name;
                String tipus=elem.typename;
                GraphLayout.GraphNode node=layout.nodes[net.collection.indexOf(elem)];
                int x=20+node.x;
                int y=20+node.y;

                g.setColor(Color.white);
                g.fillRect( x, y, 72, 72);
                g.setColor(Color.black);
                g.drawRect( x, y, 72, 72);

                g.drawString(nev,x+5,y+15);
                g.drawString(tipus,x+5,y+30);
            }
        }
    }

    /**
     * Konstruktor. Lerealja az controlt es azosszes alcontrolt.
     * @param anet A modell
     * @param aupdatelistener Az observer, ami a modell valtozasaira reagal
     */
    public NetworkControl(Network anet,NetworkUpdateListener aupdatelistener){
        super();
        net=anet;
        updatelistener=aupdatelistener;
        this.setLayout(null);
        createAll();
        validateTree();
        
    }

    /**
     * A java hivja meg a fuggenyt, ha ujra kel rajzolni a controlt
     * @param g
     */
    @Override
    public void paint(Graphics g){
        g.drawImage(hatter,0,0,null);
        super.paint(g);
    }

    /**
     * A java hivja meg a fuggvenyt, ha ervenytelenitve lett a control.
     * Jelen esetben minden alcontrolt ervenytelenit.
     */
    @Override
    public void invalidate(){
        super.invalidate();
        for (Component cmp:this.getComponents())
            cmp.invalidate();
    }

}
